<?php
// +----------------------------------------------------------------------
// | 公共函数库
// +----------------------------------------------------------------------
// | @link ( http://www.yurnero.net )
// +----------------------------------------------------------------------
// | @copyright
// +----------------------------------------------------------------------
// | @licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | @author Haijun Wu <nicholasinlove@126.com>
// +----------------------------------------------------------------------
// | $Id: common.inc.php 117 2011-05-12 03:42:14Z nicholasinlove1986@gmail.com $
// +----------------------------------------------------------------------


if (!defined('IN_BLOG')) {
    die('Hacking attempt');
}

/**
 * 获取用户ip
 *
 * @return  string
 */
function get_client_ip() {
	if (getenv ( "HTTP_CLIENT_IP" ) && strcasecmp ( getenv ( "HTTP_CLIENT_IP" ), "unknown" ))
		$ip = getenv ( "HTTP_CLIENT_IP" );
	else if (getenv ( "HTTP_X_FORWARDED_FOR" ) && strcasecmp ( getenv ( "HTTP_X_FORWARDED_FOR" ), "unknown" ))
		$ip = getenv ( "HTTP_X_FORWARDED_FOR" );
	else if (getenv ( "REMOTE_ADDR" ) && strcasecmp ( getenv ( "REMOTE_ADDR" ), "unknown" ))
		$ip = getenv ( "REMOTE_ADDR" );
	else if (isset ( $_SERVER ['REMOTE_ADDR'] ) && $_SERVER ['REMOTE_ADDR'] && strcasecmp ( $_SERVER ['REMOTE_ADDR'], "unknown" ))
		$ip = $_SERVER ['REMOTE_ADDR'];
	else
		$ip = "unknown";
	return ($ip);
}


/**
 +----------------------------------------------------------
 * 字符串截取，支持中文和其他编码
 +----------------------------------------------------------
 * @static
 * @access public
 +----------------------------------------------------------
 * @param string $str 需要转换的字符串
 * @param string $start 开始位置
 * @param string $length 截取长度
 * @param string $charset 编码格式
 * @param string $suffix 截断显示字符
 +----------------------------------------------------------
 * @return string
 +----------------------------------------------------------
 */
function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true) {
    if(function_exists("mb_substr")) {
		if ($suffix && strlen($str)>$length)
			return mb_substr($str, $start, $length, $charset)."...";
		else
			return mb_substr($str, $start, $length, $charset);
    }
    elseif (function_exists('iconv_substr')) {
        if ($suffix && strlen($str)>$length)
			return iconv_substr($str,$start,$length,$charset)."...";
        else
			return iconv_substr($str,$start,$length,$charset);
    }
    $re['utf-8']  = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
    $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
    $re['gbk']    = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
    $re['big5']   = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
    preg_match_all($re[$charset], $str, $match);
    $slice = join("",array_slice($match[0], $start, $length));
    if($suffix) return $slice."...";
    return $slice;
}

/**
 * 获得当前格林威治时间的时间戳
 *
 * @return  integer
 */
function gmtime() {
    return (time() - date('Z'));
}

/**
 * 获得服务器的时区
 *
 * @return  integer
 */
function server_timezone() {
    if (function_exists('date_default_timezone_get')) {
        return date_default_timezone_get();
    } else {
        return date('Z') / 3600;
    }
}

/**
 *  生成一个用户自定义时区日期的GMT时间戳
 *
 * @access  public
 * @param   int     $hour
 * @param   int     $minute
 * @param   int     $second
 * @param   int     $month
 * @param   int     $day
 * @param   int     $year
 *
 * @return void
 */
function local_mktime($hour = NULL , $minute= NULL, $second = NULL,  $month = NULL,  $day = NULL,  $year = NULL) {
    $timezone = C('server_timezone')? C('server_timezone') : '8';
    /**
    * $time = mktime($hour, $minute, $second, $month, $day, $year) - date('Z') + (date('Z') - $timezone * 3600)
    * 先用mktime生成时间戳，再减去date('Z')转换为GMT时间，然后修正为用户自定义时间。以下是化简后结果
    **/
    $time = mktime($hour, $minute, $second, $month, $day, $year) - $timezone * 3600;

    return $time;
}

/**
 *  将一个用户自定义时区的日期转为GMT时间戳
 *
 * @access  public
 * @param   string      $str
 *
 * @return  integer
 */
function local_strtotime($str) {
    $timezone = C('server_timezone')? C('server_timezone') : '8';
    /**
    * $time = mktime($hour, $minute, $second, $month, $day, $year) - date('Z') + (date('Z') - $timezone * 3600)
    * 先用mktime生成时间戳，再减去date('Z')转换为GMT时间，然后修正为用户自定义时间。以下是化简后结果
    **/
    $time = strtotime($str) - $timezone * 3600;
    return $time;
}

/**
 * 将GMT时间戳格式化为用户自定义时区日期
 *
 * @param  string       $format
 * @param  integer      $time       该参数必须是一个GMT的时间戳
 *
 * @return  string
 */

function local_date($format, $time = NULL) {  
	$timezone = C('server_timezone')? C('server_timezone') : '8';
    if ($time === NULL) {
        $time = gmtime();
    } elseif ($time <= 0) {
        return '';
    }
    $time += ($timezone * 3600);
    return gmdate($format, $time);
}

/**
 * 获得用户所在时区指定的日期和时间信息
 *
 * @param   $timestamp  integer     该时间戳必须是一个服务器本地的时间戳
 *
 * @return  array
 */
function local_getdate($timestamp = NULL) {
    $timezone = C('server_timezone')? C('server_timezone') : '8';
    /* 如果时间戳为空，则获得服务器的当前时间 */
    if ($timestamp === NULL) {
        $timestamp = time();
    }
    $gmt        = $timestamp - date('Z');       // 得到该时间的格林威治时间
    $local_time = $gmt + ($timezone * 3600);    // 转换为用户所在时区的时间戳
    return getdate($local_time);
}

/**
 * 获取系统配置
 *
 * @access  public
 * @return  void
 */
function get_config($rewrite = false) {
	$php_self = addslashes(htmlspecialchars($_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']));
	$path = ROOT_PATH.STATIC_CACHES_DIR;
	$arr = array();
	if (file_exists($path.'system_config_static.php')) {
	   $arr = f_static_cache('system_config_static','',$path);
	} else {
		$conf  =  M('Config');
		$data  = $conf->findAll();
		foreach ($data as $row) {
			$arr[$row['config_name']] = $row['config_value'];
		}
		
		$arr['blog_domain']            = !empty($arr['blog_domain']) ? trim($arr['blog_domain']) : 'http://'.$_SERVER['HTTP_HOST'].dirname($php_self).'/';
		//待续
		$arr['posts_num']              = !empty($arr['posts_num']) ? intval($arr['posts_num']) : 10;
		$arr['related_posts_num']      = !empty($arr['related_posts_num']) ? intval($arr['related_posts_num']) : 0;
		$arr['comment_num']            = !empty($arr['comment_num']) ? intval($arr['comment_num']) : 15;
		$arr['guestbook_num']          = !empty($arr['guestbook_num']) ? intval($arr['guestbook_num']) : 15;
		$arr['rss_num']                = !empty($arr['rss_num']) ? intval($arr['rss_num']) : 15;
		$arr['admin_list_num']         = !empty($arr['admin_list_num']) ? intval($arr['admin_list_num']) : 15;
		$arr['page_roll']              = !empty($arr['page_roll']) ? intval($arr['page_roll']) : 5;
		$arr['posts_title_limit']      = !empty($arr['posts_title_limit']) ? intval($arr['posts_title_limit']) : 0;
		$arr['related_title_limit']    = !empty($arr['related_title_limit']) ? intval($arr['related_title_limit']) : 0;	
		$arr['recent_comments_num']    = !empty($arr['recent_comments_num']) ? intval($arr['recent_comments_num']) : 10;
		$arr['recent_comments_limit']  = !empty($arr['recent_comments_limit']) ? intval($arr['recent_comments_limit']) : 15;
		$arr['comment_minlength']      = !empty($arr['comment_minlength']) ? intval($arr['comment_minlength']) : 4;
		$arr['comment_maxlength']      = !empty($arr['comment_maxlength']) ? intval($arr['comment_maxlength']) : 6000;  
		$arr['trackback_num']          = !empty($arr['trackback_num']) ? intval($arr['trackback_num']) : 10;
			
		f_static_cache('system_config_static',$arr ,$path); 
	  
	}
	if ($rewrite) {
		$path_ = ROOT_PATH.'Includes/config.user.php';
		$userConfig = "<?php\r\n// +----------------------------------------------------------------------
// | 用户扩展配置
// +----------------------------------------------------------------------
// | @link
// +----------------------------------------------------------------------
// | @copyright
// +----------------------------------------------------------------------
// | @licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | @author Haijun Wu <nicholasinlove@126.com>
// +----------------------------------------------------------------------
// | \$Id\$
// +----------------------------------------------------------------------\r\n\r\n
if (!defined('THINK_PATH')) exit();\r\nreturn array(\r\n";		
		$userConfig .= "\t'URL_MODEL'=>".$arr['url_model'].",\r\n";
		if ($arr['enable_html']) {
			$userConfig .= "\t'URL_HTML_SUFFIX'=>'".$arr['html_ext']."',\r\n";
		}
		$userConfig .= ");\r\n?>";
	
		file_put_contents($path_,$userConfig);
	}
	foreach ($arr as $key => $v) {
		C($key,$v);
	}
	C('COOKIEPATH', preg_replace('|https?://[^/]+|i', '', C('blog_domain')));
	C('COOKIEHASH', md5(C('blog_domain')));
	C('COOKIEDOMAIN', false);
	if (!C('blog_domain')) {		
		C('blog_domain','http://'.$_SERVER['HTTP_HOST'].dirname($php_self).'/');
	}
	return $arr;
}

/**
 * url编码解码
 *
 * @access  public
 * @return  string
 */
function url_encode($string) {
	return urlencode($string);
}

function url_decode($string) {
	return urldecode($string);
}

// 快速文件数据读取和保存 针对简单类型数据 字符串、数组(修改版
function f_static_cache($name,$value='',$path=DATA_PATH) {
    static $_cache = array();
    $filename   =   $path.$name.'.php';
    if('' !== $value) {
        if(is_null($value)) {
            // 删除缓存
            return unlink($filename);
        }else{
            // 缓存数据
            $dir   =  dirname($filename);
            // 目录不存在则创建
            if(!is_dir($dir))  mkdir($dir);
            return file_put_contents($filename,"<?php\n//nblog cache file\n//Created on " . date('Y-m-d H:i:s',time()) . "\n\nif (!defined('IN_BLOG')) exit('Hacking attempt');\n\n\$data = ".var_export($value,true)."\n?>");
        }
    }
    if(isset($_cache[$name])) return $_cache[$name];
    // 获取缓存数据
    if(is_file($filename)) {
        include ($filename);
        $_cache[$name]   =   $data;
    }else{
        $data  =   false;
    }
    return $data;
}

/**
 +----------------------------------------------------------
 * 代码加亮
 +----------------------------------------------------------
 * @param String  $str 要高亮显示的字符串 或者 文件名
 * @param Boolean $show 是否输出
 +----------------------------------------------------------
 * @return String
 +----------------------------------------------------------
 */
function highlight_code($str,$show=false) {
    if(file_exists($str)) {
        $str    =   file_get_contents($str);
    }
    $str  =  stripslashes(trim($str));
    // The highlight string function encodes and highlights
    // brackets so we need them to start raw
    $str = str_replace(array('&lt;', '&gt;'), array('<', '>'), $str);

    // Replace any existing PHP tags to temporary markers so they don't accidentally
    // break the string out of PHP, and thus, thwart the highlighting.

    $str = str_replace(array('&lt;?php', '?&gt;',  '\\'), array('phptagopen', 'phptagclose', 'backslashtmp'), $str);

    // The highlight_string function requires that the text be surrounded
    // by PHP tags.  Since we don't know if A) the submitted text has PHP tags,
    // or B) whether the PHP tags enclose the entire string, we will add our
    // own PHP tags around the string along with some markers to make replacement easier later

    $str = '<?php //tempstart'."\n".$str.'//tempend ?>'; // <?

    // All the magic happens here, baby!
    $str = highlight_string($str, TRUE);

    // Prior to PHP 5, the highlight function used icky font tags
    // so we'll replace them with span tags.
    if (abs(phpversion()) < 5) {
        $str = str_replace(array('<font ', '</font>'), array('<span ', '</span>'), $str);
        $str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);
    }

    // Remove our artificially added PHP
    $str = preg_replace("#\<code\>.+?//tempstart\<br />\</span\>#is", "<code>\n", $str);
    $str = preg_replace("#\<code\>.+?//tempstart\<br />#is", "<code>\n", $str);
    $str = preg_replace("#//tempend.+#is", "</span>\n</code>", $str);

    // Replace our markers back to PHP tags.
    $str = str_replace(array('phptagopen', 'phptagclose', 'backslashtmp'), array('&lt;?php', '?&gt;', '\\'), $str); //<?
    $line   =   explode("<br />", rtrim(ltrim($str,'<code>'),'</code>'));
    $result =   '<div class="code"><ol>';
    foreach($line as $key=>$val) {
        $result .=  '<li>'.$val.'</li>';
    }
    $result .=  '</ol></div>';
    $result = str_replace("\n", "", $result);
    if( $show!== false) {
        echo($result);
    }else {
        return $result;
    }
}

/**
 * 发送trackback
 *
 * @access  public
 * @return  String
 */
function trackback_send($url, $data) {
	$uinfo = parse_url($url);
	if ($uinfo['query']) {
		$data .= '&'.$uinfo['query'];
	}
	if (!$fp = @fsockopen($uinfo['host'], ($uinfo['port'] ? $uinfo['port'] : '80'), $errno, $errstr, 3)) {
		return false;
	}
	fputs ($fp, "POST ".$uinfo['path']." HTTP/1.1\r\n");
	fputs ($fp, "Host: ".$uinfo['host']."\r\n");
	fputs ($fp, "Content-type: application/x-www-form-urlencoded\r\n");
	fputs ($fp, "Content-length: ".strlen($data)."\r\n");
	fputs ($fp, "Connection: close\r\n\r\n");
	fputs ($fp, $data);
	$http_response = '';
	while(!feof($fp)) {
		$http_response .= fgets($fp, 128);
	}
	@fclose($fp);
	list($http_headers, $http_content) = explode('\r\n\r\n', $http_response);
	return $http_response;
}

/**
 * 递归方式的对变量中的特殊字符进行转义
 *
 * @access  public
 * @param   mix     $value
 *
 * @return  mix
 */
function addslashes_deep($value) {
    if (empty($value)) {
        return $value;
    } else {
        return is_array($value) ? array_map('addslashes_deep', $value) : addslashes($value);
    }
}

/**
 * 递归方式的对变量中的特殊字符去除转义
 *
 * @access  public
 * @param   mix     $value
 *
 * @return  mix
 */
function stripslashes_deep($value) {
    if (empty($value)) {
        return $value;
    } else {
        return is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
    }
}

/**
 * 获得系统是否启用了 gzip
 *
 * @access  public
 *
 * @return  boolean
 */
function gzip_enabled() {
    static $enabled_gzip = NULL;
    if ($enabled_gzip === NULL) {
        $enabled_gzip = (C('gzip') && function_exists('ob_gzhandler'));
    }
    return $enabled_gzip;
}

/**
 * 输出安全的 html
 *
 * @access  public
 *
 * @return  string
 */
function h($text, $tags = null){
	$text	=	trim($text);
	//完全过滤注释
	$text	=	preg_replace('/<!--?.*-->/','',$text);
	//完全过滤动态代码
	$text	=	preg_replace('/<\?|\?'.'>/','',$text);
	//完全过滤js
	$text	=	preg_replace('/<script?.*\/script>/','',$text);

	$text	=	str_replace('[','&#091;',$text);
	$text	=	str_replace(']','&#093;',$text);
	$text	=	str_replace('|','&#124;',$text);
	//过滤换行符
	$text	=	preg_replace('/\r?\n/','',$text);
	//br
	$text	=	preg_replace('/<br(\s\/)?'.'>/i','[br]',$text);
	$text	=	preg_replace('/(\[br\]\s*){10,}/i','[br]',$text);
	//过滤危险的属性，如：过滤on事件lang js
	while(preg_match('/(<[^><]+)( lang|on|action|background|codebase|dynsrc|lowsrc)[^><]+/i',$text,$mat)){
		$text=str_replace($mat[0],$mat[1],$text);
	}
	while(preg_match('/(<[^><]+)(window\.|javascript:|js:|about:|file:|document\.|vbs:|cookie)([^><]*)/i',$text,$mat)){
		$text=str_replace($mat[0],$mat[1].$mat[3],$text);
	}
	if(empty($tags)) {
		$tags = 'table|td|th|tr|i|b|u|strong|img|p|br|div|strong|em|ul|ol|li|dl|dd|dt|a';
	}
	//允许的HTML标签
	$text	=	preg_replace('/<('.$tags.')( [^><\[\]]*)>/i','[\1\2]',$text);
	//过滤多余html
	$text	=	preg_replace('/<\/?(html|head|meta|link|base|basefont|body|bgsound|title|style|script|form|iframe|frame|frameset|applet|id|ilayer|layer|name|script|style|xml)[^><]*>/i','',$text);
	//过滤合法的html标签
	while(preg_match('/<([a-z]+)[^><\[\]]*>[^><]*<\/\1>/i',$text,$mat)){
		$text=str_replace($mat[0],str_replace('>',']',str_replace('<','[',$mat[0])),$text);
	}
	//转换引号
	while(preg_match('/(\[[^\[\]]*=\s*)(\"|\')([^\2=\[\]]+)\2([^\[\]]*\])/i',$text,$mat)){
		$text=str_replace($mat[0],$mat[1].'|'.$mat[3].'|'.$mat[4],$text);
	}
	//过滤错误的单个引号
	while(preg_match('/\[[^\[\]]*(\"|\')[^\[\]]*\]/i',$text,$mat)){
		$text=str_replace($mat[0],str_replace($mat[1],'',$mat[0]),$text);
	}
	//转换其它所有不合法的 < >
	$text	=	str_replace('<','&lt;',$text);
	$text	=	str_replace('>','&gt;',$text);
	$text	=	str_replace('"','&quot;',$text);
	 //反转换
	$text	=	str_replace('[','<',$text);
	$text	=	str_replace(']','>',$text);
	$text	=	str_replace('|','"',$text);
	//过滤多余空格
	$text	=	str_replace('  ',' ',$text);
	return $text;
}

/**
 * 自动识别编码函数
 *
 * @access  public
 *
 * @return  string
 */
function auto_encode($string,$outEncoding = 'UTF-8') {  
    $encoding = "UTF-8";  
    for($i=0;$i<strlen($string);$i++) {  
        if(ord($string{$i})<128)  
            continue;  

        if((ord($string{$i})&224)==224) {  
            //第一个字节判断通过  
            $char = $string{++$i};  
            if((ord($char)&128)==128) {  
                //第二个字节判断通过  
                $char = $string{++$i};  
                if((ord($char)&128)==128) {  
                    $encoding = "UTF-8";  
                    break;  
                }  
            }  
        }  
        if((ord($string{$i})&192)==192){  
            //第一个字节判断通过  
            $char = $string{++$i};  
            if((ord($char)&128)==128) {  
                //第二个字节判断通过  
                $encoding = "GB2312";  
                break;  
            }  
        }  
    }  
      
    if(strtoupper($encoding) == strtoupper($outEncoding))  
        return $string;  
    else 
        return iconv($encoding,$outEncoding,$string);  
} 

/**
 * 获取某月日志数,供日历调用
 *
 * @access  public
 *
 * @return  array
 */
function get_posts_from_date($start_time,$end_time) {
	$posts = M('Posts');
	$list = $posts->where("posts_status = 1 and posts_type = 1 and posts_draft = 1 and posts_addtime >=$start_time and posts_addtime <$end_time")->field('posts_addtime')->select();
	$posts_nums = array();
	if(is_array($list)) {
		foreach ($list as $key =>$v) {
			foreach ($v as $k=>$c){
				$day = local_date('j', $c); 
				if (!isset($posts_nums[$day])) {
					$posts_nums[$day] = 1;
				} else {
					$posts_nums[$day]++;
				}
			}
		}
		return $posts_nums;
	}
}

/**
 * Get either a Gravatar URL or complete image tag for a specified email address.
 *
 * @param string $email The email address
 * @param string $s Size in pixels, defaults to 80px [ 1 - 512 ]
 * @param string $d Default imageset to use [ 404 | mm | identicon | monsterid | wavatar ]
 * @param string $r Maximum rating (inclusive) [ g | pg | r | x ]
 * @param boole $img True to return a complete IMG tag False for just the URL
 * @param array $atts Optional, additional key/value attributes to include in the IMG tag
 * @return String containing either just a URL or a complete image tag
 * @source http://gravatar.com/site/implement/images/php/
 */
function get_gravatar( $email, $s = 80, $d = 'mm', $r = 'g', $img = false, $atts = array() ) {
	$url = 'http://www.gravatar.com/avatar/';
	$url .= md5( strtolower( trim( $email ) ) );
	$url .= "?s=$s&d=$d&r=$r";
	if ( $img ) {
		$url = '<img src="' . $url . '"';
		foreach ( $atts as $key => $val )
			$url .= ' ' . $key . '="' . $val . '"';
		$url .= ' />';
	}
	return $url;
}

/**
 * Convert text equivalent of smilies to images.
 *
 * Will only convert smilies if the option 'use_smilies' is true and the global
 * used in the function isn't empty.
 *
 * @since 0.71
 * @uses $wp_smiliessearch
 *
 * @param string $text Content to convert smilies from text.
 * @return string Converted content with text smilies replaced with images.
 */
function convert_smilies($text) {
	global $wp_smiliessearch;
	$output = '';
	if (!empty($wp_smiliessearch) ) {
		// HTML loop taken from texturize function, could possible be consolidated
		$textarr = preg_split("/(<.*>)/U", $text, -1, PREG_SPLIT_DELIM_CAPTURE); // capture the tags as well as in between
		$stop = count($textarr);// loop stuff
		for ($i = 0; $i < $stop; $i++) {
			$content = $textarr[$i];
			if ((strlen($content) > 0) && ('<' != $content{0})) { // If it's not a tag
				$content = preg_replace_callback($wp_smiliessearch, 'translate_smiley', $content);
			}
			$output .= $content;
		}
	} else {
		// return default text.
		$output = $text;
	}
	return $output;
}


/**
 * Convert one smiley code to the icon graphic file equivalent.
 *
 * Looks up one smiley code in the $wpsmiliestrans global array and returns an
 * <img> string for that smiley.
 *
 * @global array $wpsmiliestrans
 * @since 2.8.0
 *
 * @param string $smiley Smiley code to convert to image.
 * @return string Image string for smiley.
 */
function translate_smiley($smiley) {
	global $wpsmiliestrans;

	if (count($smiley) == 0) {
		return '';
	}

	$smiley = trim(reset($smiley));
	$img = $wpsmiliestrans[$smiley];

	return " <img src=\"" . WEB_PUBLIC_PATH . "/Plugins/emoticons/smilies/$img\" alt='$smiley' class='wp-smiley'/> ";
}



/**
 * Convert smiley code to the icon graphic file equivalent.
 *
 * You can turn off smilies, by going to the write setting screen and unchecking
 * the box, or by setting 'use_smilies' option to false or removing the option.
 *
 * Plugins may override the default smiley list by setting the $wpsmiliestrans
 * to an array, with the key the code the blogger types in and the value the
 * image file.
 *
 * The $wp_smiliessearch global is for the regular expression and is set each
 * time the function is called.
 *
 * The full list of smilies can be found in the function and won't be listed in
 * the description. Probably should create a Codex page for it, so that it is
 * available.
 *
 * @global array $wpsmiliestrans
 * @global array $wp_smiliessearch
 * @since 2.2.0
 */
function smilies_init() {
	global $wpsmiliestrans, $wp_smiliessearch;

	if ( !isset( $wpsmiliestrans ) ) {
		$wpsmiliestrans = array(
		':mrgreen:' => 'icon_mrgreen.gif',
		':neutral:' => 'icon_neutral.gif',
		':twisted:' => 'icon_twisted.gif',
		  ':arrow:' => 'icon_arrow.gif',
		  ':shock:' => 'icon_eek.gif',
		  ':smile:' => 'icon_smile.gif',
		    ':???:' => 'icon_confused.gif',
		   ':cool:' => 'icon_cool.gif',
		   ':evil:' => 'icon_evil.gif',
		   ':grin:' => 'icon_biggrin.gif',
		   ':idea:' => 'icon_idea.gif',
		   ':oops:' => 'icon_redface.gif',
		   ':razz:' => 'icon_razz.gif',
		   ':roll:' => 'icon_rolleyes.gif',
		   ':wink:' => 'icon_wink.gif',
		    ':cry:' => 'icon_cry.gif',
		    ':eek:' => 'icon_surprised.gif',
		    ':lol:' => 'icon_lol.gif',
		    ':mad:' => 'icon_mad.gif',
		    ':sad:' => 'icon_sad.gif',
		      '8-)' => 'icon_cool.gif',
		      '8-O' => 'icon_eek.gif',
		      ':-(' => 'icon_sad.gif',
		      ':-)' => 'icon_smile.gif',
		      ':-?' => 'icon_confused.gif',
		      ':-D' => 'icon_biggrin.gif',
		      ':-P' => 'icon_razz.gif',
		      ':-o' => 'icon_surprised.gif',
		      ':-x' => 'icon_mad.gif',
		      ':-|' => 'icon_neutral.gif',
		      ';-)' => 'icon_wink.gif',
		       '8)' => 'icon_cool.gif',
		       '8O' => 'icon_eek.gif',
		       ':(' => 'icon_sad.gif',
		       ':)' => 'icon_smile.gif',
		       ':?' => 'icon_confused.gif',
		       ':D' => 'icon_biggrin.gif',
		       ':P' => 'icon_razz.gif',
		       ':o' => 'icon_surprised.gif',
		       ':x' => 'icon_mad.gif',
		       ':|' => 'icon_neutral.gif',
		       ';)' => 'icon_wink.gif',
		      ':!:' => 'icon_exclaim.gif',
		      ':?:' => 'icon_question.gif',
		);
	}

	if (count($wpsmiliestrans) == 0) {
		return;
	}

	/*
	 * NOTE: we sort the smilies in reverse key order. This is to make sure
	 * we match the longest possible smilie (:???: vs :?) as the regular
	 * expression used below is first-match
	 */
	krsort($wpsmiliestrans);

	$wp_smiliessearch = '/(?:\s|^)';

	$subchar = '';
	foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
		$firstchar = substr($smiley, 0, 1);
		$rest = substr($smiley, 1);

		// new subpattern?
		if ($firstchar != $subchar) {
			if ($subchar != '') {
				$wp_smiliessearch .= ')|(?:\s|^)';
			}
			$subchar = $firstchar;
			$wp_smiliessearch .= preg_quote($firstchar, '/') . '(?:';
		} else {
			$wp_smiliessearch .= '|';
		}
		$wp_smiliessearch .= preg_quote($rest, '/');
	}

	$wp_smiliessearch .= ')(?:\s|$)/m';
}

/**
 * 处理日志评论数动态更新
 *
 * @access  public
 * @param   array/string     $comment_id 支持数组或者字符串
 * @param   string           $status     状态
 *
 * @return  bool
 */
function comment_init($comment_id, $status) {
	$posts = M('Posts');
	$com   = M('Comment');
	// 更新单个
	if (is_string($comment_id)) {
		$posts_id =  $com->where("comment_id=$comment_id")->getField('posts_id');
		if ($posts_id != '0') {
			if ($status) {
				$posts->setInc('posts_comment', "posts_id = '$posts_id'");
			} else {
				$posts->setDec('posts_comment', "posts_id = '$posts_id'");
			}
		}
	}
	// 更新多个
	if (is_array($comment_id)) {
		foreach ($comment_id as $comment_id) {
			comment_init($comment_id, $status);
		}
	}
}

/**
 * 重建所有日志中的评论数,引用数和标签
 *
 * @access  public
 *
 * @return  void
 */
function rebuild_posts() {

	$posts = D('Posts');
	$com   = M('Comment');
	$tb    = M('Trackback');
	$res   = $posts->field('posts_id')->relation(true)->findAll();
	$res_count = count($res);
	
	for ($i=0; $i<$res_count; $i++) {
	
		if ($res[$i]['posts_id'] == '') continue;
		
		$comment_map = array();
		$posts_map = array();
		$tb_map = array();
				
		$posts_map['posts_id']   = $res[$i]['posts_id'];
		
		$comment_map['posts_id'] = $res[$i]['posts_id'];				
		$comment_map['comment_status'] = 1; 
		$comment_map['comment_visible'] = 1;
		$comment_map['comment_type'] = 1;
		
		$tb_map['posts_id']     = $res[$i]['posts_id'];
		$tb_map['tb_visible']   = 1;
		
		if (C('remark')) {
			$comment_map['comment_remark'] = 1;
		}
		
		$comment_num = $com->where($comment_map)->count();
		$trackback_num = $tb->where($tb_map)->count();
		
		if (is_array($res[$i]['tag']) && !empty($res[$i]['tag'])) {
			foreach ($res[$i]['tag'] as $k => $v) {
				$str .= implode(',',$v).',';
			}
			$str = substr($str,0,strlen($str)-1);
			$posts->where($posts_map)->setField(array('posts_comment','posts_tracknum','posts_tag'),array($comment_num,$trackback_num,$str));	
			$str = '';	
		} else {
			$posts->where($posts_map)->setField(array('posts_comment','posts_tracknum'),array($comment_num,$trackback_num));			
		}	
	}
	//clear_compiled_files();
}

/**
 * 重建日志中的评论数
 *
 * @access  public
 * 
 * @return  void
 */
function rebuild_comment() {
	$posts = M('Posts');
	$com   = M('Comment');
	$res = $posts->field('posts_id')->findAll();
	$res_count = count($res);
	
	for($i=0; $i<$res_count; $i++) {
	
		if($res[$i]['posts_id'] == '') continue;
		
		$comment_map = array();
		$posts_map = array();
				
		$posts_map['posts_id']   = $res[$i]['posts_id'];
		
		$comment_map['posts_id'] = $res[$i]['posts_id'];				
		$comment_map['comment_status'] = 1; 
		$comment_map['comment_visible'] = 1;
		$comment_map['comment_type'] = 1;
		
		if (C('remark')) {
			$comment_map['comment_remark'] = 1;
		}
		
		$comment_num = $com->where($comment_map)->count();	
		$posts->where($posts_map)->setField('posts_comment', $comment_num);			
	}
}

/**
 * 重建日志中的引用数
 *
 * @access  public
 * 
 * @return  void
 */
function rebuild_trackback() {

	$posts = M('Posts');
	$tb    = M('Trackback');
	$res = $posts->field('posts_id')->findAll();
	$res_count = count($res);
	
	for($i=0; $i<$res_count; $i++) {
	
		if($res[$i]['posts_id'] == '') continue;
		
		$posts_map = array();
		$tb_map = array();
				
		$posts_map['posts_id']   = $res[$i]['posts_id'];		
		$tb_map['posts_id']      = $res[$i]['posts_id'];
		$tb_map['tb_visible'] = 1;

		$trackback_num = $tb->where($tb_map)->count();
		$posts->where($posts_map)->setField('posts_tracknum',$trackback_num);			
	}
}

/**
 * 重建日志中的标签
 *
 * @access  public
 * 
 * @return  array
 */
function rebuild_tag() {

	$posts = D('Posts');
	$posts_map = array();
	$list = $posts->field('posts_id')->relation(true)->findAll();
	$count = count($list);
	for ($i=0; $i<$count; $i++) {
		if (is_array($list[$i]['tag']) && !empty($list[$i]['tag'])) {
			foreach ($list[$i]['tag'] as $k => $v) {
				$str .= implode(',',$v).',';
			}
			$str = substr($str,0,strlen($str)-1);
			$posts_map['posts_id']   = $list[$i]['posts_id'];
			$posts->where($posts_map)->setField('posts_tag',$str);
			$tag[$list[$i]['posts_id']][] = $str;
			$str = '';	
		}
	}
	return $tag;
}

?>